home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok59.lha
/
AmokEd_V1.02b
/
txt
/
EdBlocks.mod
< prev
next >
Wrap
Text File
|
1993-08-15
|
10KB
|
374 lines
(*************************************************************************
:Program. EdBlocks.mod
:Contents. Routines for Block-Handling for AmokEd
:Author. Hartmut Goebel
:Language. Oberon
:Translator. Oberon Compiler V1.17.1
:History. V0.1 12 Jan 1991 Hartmut Goebel [hG]
:History. V1.0 14 Apr 1991 [hG]
:History. V1.1 07 Jul 1991 [hG] +HoldExtPingPong in HoldBlockLines
:Date. 07 Jul 1991 18:37:49
*************************************************************************)
MODULE EdBlocks;
IMPORT
e: Exec,
eAD: EdApplDefs,
edD: EdDisplay,
edE: EdErrors,
edG: EdGlobalVars,
edL: EdLowLevel,
lst: EdLists,
ol : OberonLib,
sys: SYSTEM;
CONST
BlockBegin = "Block Begin";
BlockEnd = "Block End";
BlockAlreadyMarked = "Block Already Marked";
BlockUnmarked = "Block Unmarked";
BlockNotSpecified = "Block Not Specified";
CannotMoveIntoSelf = "Cannot Move into self";
PushmarkStackLimitReached = "pushmark: stack limit reached";
On = TRUE;
Off = FALSE;
(* Schaltet Blockanzeige an oder aus (ggf. mit Unblock) *)
PROCEDURE DisplayBlock(on: BOOLEAN);
VAR
start, lines: INTEGER;
txt: edG.TextHeaderPtr;
BEGIN
IF (edG.Block.ENum<0) (* not specified *)
OR (edG.iconMode IN edG.Block.Owner.status)
OR (edG.Block.Owner.topLine+edG.Rows<edG.Block.SNum) (* not visible *)
THEN RETURN; END;
txt := NIL;
IF edG.Block.Owner#edG.Text THEN
txt := edG.Text;
edD.SwitchEdit(edG.Block.Owner);
END;
start := 0;
IF start < edG.Block.SNum-edG.Text.topLine THEN
start := SHORT(edG.Block.SNum-edG.Text.topLine) END;
lines := edG.Rows;
IF lines > edG.Block.ENum - edG.Block.SNum + 1 THEN
lines := SHORT(edG.Block.ENum - edG.Block.SNum + 1); END;
IF NOT on THEN
edG.Block.SNum := -1; edG.Block.ENum := -1; END;
edD.TextDisplaySeg(start,lines);
IF txt#NIL THEN
edD.SwitchEdit(txt); END;
END DisplayBlock;
(* Text-Refresh für Block.Owner mit Unblock (nach BDelete/BMove) *)
PROCEDURE RedrawBlockOwner;
VAR
txt: edG.TextHeaderPtr;
BEGIN
edG.Block.SNum := -1; edG.Block.ENum := -1;
IF edG.iconMode IN edG.Block.Owner.status THEN RETURN END;
txt := NIL;
IF edG.Block.Owner#edG.Text THEN
txt := edG.Text; edD.SwitchEdit(edG.Block.Owner); END;
edD.TextRedisplay;
IF txt#NIL THEN edD.SwitchEdit(txt); END;
END RedrawBlockOwner;
PROCEDURE doUnblock*;
BEGIN
DisplayBlock(Off);
END doUnblock;
PROCEDURE doBlock*;
BEGIN
IF (edG.Block.SNum<0) OR (edG.Block.Owner#edG.Text) THEN
edG.Block.SNum := edG.Text.line;
lst.SetMark(edG.Block,edG.Text.actLinePtr,NIL);
edG.Block.Owner := edG.Text;
edG.Rc := edE.cmdValid2;
edL.Title(BlockBegin);
ELSIF edG.Block.ENum<0 THEN
IF edG.Text.line < edG.Block.SNum THEN
edG.Block.ENum := edG.Block.SNum;
edG.Block.SNum := edG.Text.line;
lst.SetMark(edG.Block,edG.Text.actLinePtr,edG.Block.mark.head);
ELSE
edG.Block.ENum := edG.Text.line;
lst.SetMark(edG.Block,NIL,edG.Text.actLinePtr);
END;
DisplayBlock(On); (* nur hier ändert sich die Anzeige *)
edG.Rc := edE.cmdValid2;
edL.Title(BlockEnd);
ELSE
edG.Rc := edE.cmdFailed; edL.Title(BlockAlreadyMarked);
END;
END doBlock;
PROCEDURE BlockSpecified*(): BOOLEAN;
BEGIN
IF edG.Block.ENum<0 THEN
edG.Rc := edE.cmdFailed; edL.Title(BlockNotSpecified);
RETURN FALSE;
END;
RETURN TRUE;
END BlockSpecified;
PROCEDURE NoMoveIntoBlock(): BOOLEAN;
BEGIN
IF (edG.Text.line>edG.Block.SNum)
AND (edG.Text.line<=edG.Block.ENum) AND (edG.Block.Owner=edG.Text) THEN
edG.Rc := edE.cmdFailed; edL.Title(CannotMoveIntoSelf);
RETURN FALSE;
END;
RETURN TRUE;
END NoMoveIntoBlock;
PROCEDURE RemBlock;
VAR
NumDelLines: LONGINT;
BEGIN
INCL(edG.Block.Owner.status,edG.modified);
IF (edG.Block.Owner.line>=edG.Block.SNum)
AND (edG.Block.Owner.line<=edG.Block.ENum) THEN
edG.Block.Owner.actLinePtr := edG.Block.mark.tail.next(edG.Line);
END;
edL.FreeLines(edG.Block.Owner.lineList,edG.Block.mark.head,edG.Block.mark.tail);
NumDelLines := edG.Block.ENum-edG.Block.SNum+1;
DEC(edG.Block.Owner.numberOfLines,NumDelLines);
IF edG.Block.Owner.line>edG.Block.SNum THEN
IF edG.Block.Owner.line <= edG.Block.ENum THEN
edG.Block.Owner.line := edG.Block.SNum;
ELSE
DEC(edG.Block.Owner.line,NumDelLines);
END;
END;
IF edG.Block.Owner.actLinePtr=NIL THEN
edG.Block.Owner.actLinePtr := edG.Block.Owner.lineList.tail;
END;
END RemBlock;
PROCEDURE CopyBlock;
VAR
Line, NewLine: edG.LinePtr;
NumMovedLines: LONGINT;
List: lst.List;
BEGIN
INCL(edG.Text.status,edG.modified);
lst.Init(List);
Line := edG.Block.mark.head(edG.Line);
LOOP
NewLine := edL.CreateLineCopy(Line);
IF NewLine#NIL THEN
lst.AddTail(List,NewLine);
ELSE
IF List.head#NIL THEN
edL.FreeLines(List,List.head(edG.Line),List.tail(edG.Line)); END;
edG.Rc := edE.cmdFailed; RETURN;
END;
IF Line = edG.Block.mark.tail THEN EXIT; END;
Line := Line.next(edG.Line);
END;
lst.AddMarkBefore(edG.Text.lineList,List,edG.Text.actLinePtr);
edG.Text.actLinePtr := List.head(edG.Line);
NumMovedLines := edG.Block.ENum-edG.Block.SNum+1;
INC(edG.Text.numberOfLines,NumMovedLines);
IF (edG.Text.line <= edG.Block.SNum) AND (edG.Block.Owner=edG.Text) THEN
INC(edG.Block.SNum,NumMovedLines);
INC(edG.Block.ENum,NumMovedLines);
IF edG.Text.line = edG.Text.topLine THEN
INC(edG.Text.topLine,NumMovedLines); END;
END;
IF edG.Text.line = edG.Text.topLine THEN
edG.Text.topLinePtr := edG.Text.actLinePtr; END;
END CopyBlock;
PROCEDURE doBDelete*;
BEGIN
IF NOT BlockSpecified() THEN RETURN; END;
edD.PutBackLine;
RemBlock;
IF edG.Text.lineList.head=NIL THEN
edL.NewLine(edG.Text.actLinePtr,edG.ChunkSize); END;
edD.TextLoad;
RedrawBlockOwner;
END doBDelete;
PROCEDURE doBCopy*;
BEGIN
IF NOT BlockSpecified() OR NOT NoMoveIntoBlock() THEN
RETURN; END;
edD.PutBackLine;
CopyBlock;
edD.TextLoad;
edD.TextRedisplay; (* TextSync macht eh' keines *)
END doBCopy;
PROCEDURE doBMove*;
BEGIN
IF NOT BlockSpecified() OR NOT NoMoveIntoBlock() THEN
RETURN; END;
edD.PutBackLine;
CopyBlock;
RemBlock;
edD.TextLoad;
RedrawBlockOwner;
IF edG.Block.Owner#edG.Text THEN edD.TextRedisplay; END;
END doBMove;
PROCEDURE HoldBlockLines*(Decrement: BOOLEAN);
VAR
i: INTEGER;
BEGIN
IF edG.Text.ExtPingPong # NIL THEN
i := 0;
REPEAT
IF edG.Text.ExtPingPong[i].line>edG.Text.line THEN
IF Decrement THEN
DEC(edG.Text.ExtPingPong[i].line);
ELSE
INC(edG.Text.ExtPingPong[i].line);
END;
END;
INC(i);
UNTIL i = eAD.NumExtPingPong;
END;
IF (edG.Text#edG.Block.Owner) OR (edG.Block.SNum<0)
OR (edG.Text.line > edG.Block.ENum) THEN
RETURN;
END;
IF (edG.Block.ENum >= 0) THEN
IF Decrement THEN
IF (edG.Text.line = edG.Block.ENum) THEN
IF edG.Block.ENum = edG.Block.SNum THEN
doUnblock;
RETURN;
END;
edG.Block.mark.head := edG.Block.mark.head.prev;
END;
DEC(edG.Block.ENum);
ELSE
INC(edG.Block.ENum);
END;
END;
IF edG.Block.SNum >= edG.Text.line THEN
IF Decrement THEN
IF (edG.Text.line = edG.Block.SNum) THEN
edG.Block.mark.head := edG.Block.mark.head.next;
ELSIF edG.Block.SNum > 0 THEN
DEC(edG.Block.SNum);
END;
ELSIF edG.Block.SNum > edG.Text.line THEN
INC(edG.Block.SNum);
END;
END;
END HoldBlockLines;
PROCEDURE doBSource*;
VAR
ThisLine, EndLine: edG.LinePtr;
Buffer: edG.StringPtr;
BEGIN
IF NOT BlockSpecified() THEN RETURN; END;
ol.New(Buffer,edG.MaxLineLength);
IF Buffer=NIL THEN
INCL(edG.Status,edG.memoryFail); edG.Rc := edE.cmdSevere;
RETURN;
END;
edD.PutBackLine;
ThisLine := edG.Block.mark.head(edG.Line);
EndLine := edG.Block.mark.tail(edG.Line);
DisplayBlock(Off);
LOOP
IF ThisLine=NIL THEN EXIT; END;
e.CopyMemQuick(ThisLine(edG.Line).string^,Buffer^,edG.MaxLineLength);
edG.ExecCmd(Buffer);
IF ThisLine = EndLine THEN EXIT; END;
ThisLine := ThisLine.next(edG.Line);
END; (* LOOP *)
DISPOSE(Buffer);
END doBSource;
(*-------------------------------------------------------------------------*)
PROCEDURE doPushMark*;
BEGIN
IF BlockSpecified() THEN
IF edG.BStackCurrDepth = edG.BlockStackSize THEN
edL.Title(PushmarkStackLimitReached); edG.Rc := edE.cmdFailed;
RETURN;
END;
edG.BStack[edG.BStackCurrDepth] := edG.Block;
INC(edG.BStackCurrDepth);
DisplayBlock(Off);
END;
END doPushMark;
PROCEDURE doPopMark*;
BEGIN
edD.PutBackLine;
DisplayBlock(Off); (* remove any existing block *)
IF edG.BStackCurrDepth = 0 THEN (* no error message on purpose *)
RETURN;
END;
DEC(edG.BStackCurrDepth);
edG.Block := edG.BStack[edG.BStackCurrDepth];
IF (edG.Block.Owner = NIL)
OR (edG.Block.ENum >= edG.Block.Owner.numberOfLines) THEN
edG.Block.Owner := NIL;
edG.Block.SNum := -1;
edG.Block.ENum := -1;
ELSE
DisplayBlock(On);
END;
END doPopMark;
PROCEDURE doSwapMark*;
VAR
i: INTEGER;
tmp: edG.BlockMark;
BEGIN
doPushMark;
IF edG.Rc = edE.cmdFailed THEN RETURN; END;
i := edG.BStackCurrDepth - 2;
IF i >= 0 THEN
tmp := edG.BStack[i];
edG.BStack[i] := edG.BStack[i+1];
edG.BStack[i+1] := tmp;
END;
doPopMark;
END doSwapMark;
PROCEDURE doPurgeMark*;
BEGIN
edG.BStackCurrDepth := 0;
END doPurgeMark;
BEGIN
edG.Block.SNum := -1; edG.Block.ENum := -1;
edG.BStackCurrDepth := 0;
END EdBlocks.